package com.kb.design.service.impl.chart;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kb.design.dto.QueryChartDTO;
import com.kb.design.entity.DesignDept;
import com.kb.design.entity.DesignPost;
import com.kb.design.entity.DesignProject;
import com.kb.design.mapper.postgreSQL.*;
import com.kb.design.service.DeptService;
import com.kb.design.service.PerformanceService;
import com.kb.design.service.PostService;
import com.kb.design.util.DateUtils;
import com.kb.design.vo.chart.DeptPerformance;
import com.kb.design.vo.chart.ProjectAndPinCountVO;
import org.aspectj.weaver.ast.Var;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;

import javax.annotation.Resource;;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Service
@DS("slave-1")
public class PerformanceServiceImpl implements PerformanceService {

    /**
     * 绩效管理查询的项目数据 全部是已经完成奖金确认的数据 既 project表中 completion_time 字段时间  时间默认是查上个月
     */
    private static final String[] COLORS = {"blue", "red", "yellow", "green", "indigo", "purple", "orange"};

    @Resource
    private ProjectMapper projectMapper;
    @Resource
    private ChartMapper chartMapper;
    @Resource
    private CustomUserMapper userMapper;
    @Resource
    private DeptService deptService;
    @Resource
    private DesignDeptMapper designDeptMapper;
    @Resource
    private PostService postMapping;

    @Override
    public List<ProjectAndPinCountVO> projectCount(QueryChartDTO queryChartDTO) {
        List<ProjectAndPinCountVO> list = new ArrayList<>();
        LambdaQueryWrapper<DesignDept> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DesignDept::getLevel, 3);
        queryWrapper.eq(DesignDept::getQueryDept, 1);
        List<DesignDept> designDepts = designDeptMapper.selectList(queryWrapper);
        //去除 部门含有 客服 字段的数据
        designDepts = designDepts.stream()
                .sorted(Comparator.comparing(DesignDept::getDeptId))
                .collect(Collectors.toList());        //查询出二级部门 再把项目查询出来 进行数据聚合
        LocalDate[] firstAndLastDayOfLastMonth;
        if (Objects.isNull(queryChartDTO.getStart())) {
            firstAndLastDayOfLastMonth = DateUtils.getFirstAndLastDayOfLastMonth();
        } else {
            firstAndLastDayOfLastMonth = DateUtils.getFirstAndLastDayOfMonth(queryChartDTO.getStart());
        }

        List<DesignProject> completedProjects = chartMapper.getCompletedProjects(firstAndLastDayOfLastMonth[0], firstAndLastDayOfLastMonth[1]);
        int size = completedProjects.size();
        BigDecimal pinCount = completedProjects.stream()
                .map(DesignProject::getPinAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        int color = 0;
        for (DesignDept dept : designDepts) {
            String deptName = dept.getDeptName();
            ProjectAndPinCountVO projectAndPinCountVO = new ProjectAndPinCountVO();
            projectAndPinCountVO.setDepartmentName(deptName);
            projectAndPinCountVO.setDepartmentName(deptName);
            //防止颜色数组下标异常
            if (color > COLORS.length) {
                color = 0;
            }
            projectAndPinCountVO.setColor(COLORS[color]);
            color++;
            List<DesignDept> deptList = Collections.emptyList();
            Integer userPinCount = 0;
            if (deptName.contains("深圳")) {
                //查询子部门的id
                deptList = deptService.queryAllDept(4L);
                userPinCount = deptService.selectUsersPinByDeptAndChildren(4L);
            }
            if (deptName.contains("西安")) {
                deptList = deptService.queryAllDept(3L);
                userPinCount = deptService.selectUsersPinByDeptAndChildren(3L);
            }
            if (deptName.contains("北京")) {
                deptList = deptService.queryAllDept(5L);
                userPinCount = deptService.selectUsersPinByDeptAndChildren(5L);
            }
            if (deptName.contains("封装")) {
                projectAndPinCountVO.setProjectCount(size);
                projectAndPinCountVO.setPinCount(pinCount);
                userPinCount = deptService.selectUsersPinByDeptAndChildren(14L);
            }
            if (deptName.contains("品质")) {
                projectAndPinCountVO.setProjectCount(size);
                projectAndPinCountVO.setPinCount(pinCount);
                userPinCount = deptService.selectUsersPinByDeptAndChildren(15L);
            }
            //根据completedProjects项目里面的 designDepartments设计部门字段，筛选出 deptList里面含有的部门数据
            Set<Long> deptIds = deptList.stream()
                    .map(DesignDept::getDeptId)
                    .collect(Collectors.toSet());
            List<DesignProject> filteredProjects = completedProjects.stream()
                    .filter(p -> p.getDesignDepartments() != null && deptIds.contains(p.getDesignDepartments().longValue()))
                    .collect(Collectors.toList());

            int projectCount = filteredProjects.size();
            BigDecimal designPinCount = filteredProjects.stream()
                    .map(DesignProject::getPinAmount)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            //达成率  总项目总pin / 人员总pin
            if (userPinCount > 0) {
                BigDecimal divide = designPinCount.divide(BigDecimal.valueOf(userPinCount), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
                projectAndPinCountVO.setAchievementRate(divide);
            }
            projectAndPinCountVO.setProjectCount(projectCount);
            projectAndPinCountVO.setPinCount(designPinCount);

            list.add(projectAndPinCountVO);
        }
        return list;
    }

    @Override
    public List<DeptPerformance> getDeptPerformance(QueryChartDTO queryChartDTO) {
        LocalDate[] firstAndLastDayOfLastMonth;
        if (Objects.isNull(queryChartDTO.getStart())) {
            firstAndLastDayOfLastMonth = DateUtils.getFirstAndLastDayOfLastMonth();
        } else {
            firstAndLastDayOfLastMonth = DateUtils.getFirstAndLastDayOfMonth(queryChartDTO.getStart());
        }
        //todo 根据部门id 查询不同的sql
        DesignDept designDept = deptService.selectDeptById(Long.valueOf(queryChartDTO.getDepartmentId()));

        int monthValue = queryChartDTO.getStart().getMonthValue();
        List<DeptPerformance> deptPerformance;
        if (!Objects.equals(queryChartDTO.getDepartmentId(), "14")) {
            deptPerformance = chartMapper.getDeptPerformance(Long.valueOf(queryChartDTO.getDepartmentId()), firstAndLastDayOfLastMonth[0], firstAndLastDayOfLastMonth[1]);
        }else {
            deptPerformance = chartMapper.getDeptPagePerformance(Long.valueOf(queryChartDTO.getDepartmentId()), firstAndLastDayOfLastMonth[0], firstAndLastDayOfLastMonth[1]);
        }

        for (DeptPerformance performance : deptPerformance) {
            performance.setDeptName(designDept.getDeptName());
            performance.setMonths(monthValue);
            DesignPost postByUserCode = postMapping.getPostByUserCode(performance.getUserCode());
            if (postByUserCode != null) {
                performance.setPositions(postByUserCode.getPostName());
                performance.setPinTarget(postByUserCode.getPinTarget());
            }
        }
        return deptPerformance;
    }

    @Override
    public Map<String, Object> getDeptPerformanceRanking(QueryChartDTO queryChartDTO) {
        Map<String, Object> map = new HashMap<>();
        LocalDate[] firstAndLastDayOfLastMonth;
        if (Objects.isNull(queryChartDTO.getStart())) {
            queryChartDTO.setStart(LocalDate.now());
        }
        firstAndLastDayOfLastMonth = DateUtils.getFirstAndLastDayOfYear(queryChartDTO.getStart());
        //获取月份 queryChartDTO.getStart()
        int monthValue = queryChartDTO.getStart().getMonthValue();
        //配合低代码  只能初始化 map.put("deptPerformance1", "");
        map.put("deptPerformance1", "");
        map.put("deptPerformance2", "");
        map.put("deptPerformance3", "");
        map.put("yearTop1", "");
        List<DeptPerformance> deptPerformance;
        if (!Objects.equals(queryChartDTO.getDepartmentId(), "14")) {
            deptPerformance = chartMapper.getDeptPerformanceRanking(Long.valueOf(queryChartDTO.getDepartmentId()), firstAndLastDayOfLastMonth[0], firstAndLastDayOfLastMonth[1]);
        }else {
            deptPerformance = chartMapper.getDeptPagePerformanceRanking(Long.valueOf(queryChartDTO.getDepartmentId()), firstAndLastDayOfLastMonth[0], firstAndLastDayOfLastMonth[1]);
        }
        for (int i = 0; i < deptPerformance.size(); i++) {
            DeptPerformance deptPerformance1 = deptPerformance.get(i);
            if (i == 0) {
                Map<String, Object> Datemap = new HashMap<>();
                Datemap.put("name", deptPerformance1.getUserName());
                Datemap.put("value", deptPerformance1.getPinNum());
                map.put("yearTop1", Datemap);
            }
            BigDecimal pinNum = deptPerformance1.getPinNum();
            Map<String, Object> Datemap = new HashMap<>();
            Datemap.put("name", deptPerformance1.getUserName());
            Datemap.put("value", pinNum.divide(BigDecimal.valueOf(monthValue), 0, RoundingMode.HALF_UP));

            map.put("deptPerformance" + (i + 1), Datemap);
        }
        DeptPerformance deptProjectNum = chartMapper.getDeptProjectNum(Long.valueOf(queryChartDTO.getDepartmentId()), firstAndLastDayOfLastMonth[0], firstAndLastDayOfLastMonth[1]);
        Map<String, Object> Datemap = new HashMap<>();
        if (deptProjectNum != null) {
            Datemap.put("name", deptProjectNum.getUserName());
            Datemap.put("value", deptProjectNum.getProjectNum());
        }
        map.put("projectNum", Datemap);
        return map;
    }

    @Override
    public List<DeptPerformance> getDeliveryList(QueryChartDTO queryChartDTO) {
        if (queryChartDTO.getDepartmentId() == null) {
            queryChartDTO.setDepartmentId("3");
        }
        LocalDate[] firstAndLastDayOfLastMonth;
        if (Objects.isNull(queryChartDTO.getStart())) {
            queryChartDTO.setStart(LocalDate.now());
        }
        firstAndLastDayOfLastMonth = DateUtils.getFirstAndLastDayOfMonth(queryChartDTO.getStart());
        List<DeptPerformance> deliveryDesignList;
        if (Objects.equals(queryChartDTO.getDepartmentId(), "14")) {
            deliveryDesignList = chartMapper.getDeliveryPageList(Long.valueOf(queryChartDTO.getDepartmentId()), firstAndLastDayOfLastMonth[0], firstAndLastDayOfLastMonth[1]);
        } else {
            deliveryDesignList = chartMapper.getDeliveryDesignList(Long.valueOf(queryChartDTO.getDepartmentId()), firstAndLastDayOfLastMonth[0], firstAndLastDayOfLastMonth[1]);
        }

        return deliveryDesignList;
    }

    @Override
    public List<DeptPerformance> getBonusDistribution(QueryChartDTO queryChartDTO) {
        if (Objects.nonNull(queryChartDTO.getDepartmentId())) {
            LocalDate[] firstAndLastDayOfLastMonth;
            if (Objects.isNull(queryChartDTO.getStart())) {
                queryChartDTO.setStart(LocalDate.now());
            }
            firstAndLastDayOfLastMonth = DateUtils.getFirstAndLastDayOfMonth(queryChartDTO.getStart());
            List<DeptPerformance>  deliveryDesignList = chartMapper.getBonusDistribution(Long.valueOf(queryChartDTO.getDepartmentId()), firstAndLastDayOfLastMonth[0], firstAndLastDayOfLastMonth[1]);
            //根据progectId倒序
            deliveryDesignList.sort(Comparator.comparing(DeptPerformance::getDesignStage).reversed());
            return deliveryDesignList;
        }
        return new ArrayList<>();
    }
}
